Documento de análise exploratoria de dados em R
# Load de variáveis e de bibliotecas
library(readxl)
library(tidyverse)
library(dplyr)
library(stringr)
library(lubridate)
library(janitor)
library(zoo)
library(tsbox)
library(forecast)
library(plotly)
library(xts) # lib para time series
library(spotifyr)
library(rmarkdown)
library(purrr)
source("multiplot.R", local = TRUE)
(A) Criação do indice de variação
indice_var <- function(x) {
indice <- x
indice[1] <- 100
for(i in 2:length(x)) {
indice[i] <- (1 + x[i]/100) * indice[i-1]
}
return(indice)
}
Filtrando por ano
load(file = "us_change.rda")
data_nivel <- us_change %>%
clean_names()
# Criando o DF com os indices e filtrando pelo ano
indice_df<- data_nivel %>%
filter(quarter >= as.Date("2000-01-01")) %>%
select(-quarter) %>%
map_df(function(x) x %>% indice_var())
# Criando DF com a coluna de data da base original
df_date <- data_nivel %>%
filter(quarter >= as.Date("2000-01-01")) %>%
select(quarter)
# Criando a coluna quarter de volta na base de indices
indice_df <- indice_df %>%
mutate(quarter = df_date$quarter)
Multiplot data
plot1 <- data_nivel %>%
dplyr::filter((quarter >= as.Date("2000-01-01"))) %>%
ggplot(aes(x = quarter, y = consumption)) +
geom_line() +
labs(title="original_consuption")
plot2 <- indice_df %>%
ggplot(aes(x = quarter, y = consumption)) +
geom_line() +
labs(title="consuption_indice")
plot3 <- data_nivel %>%
dplyr::filter((quarter >= as.Date("2000-01-01"))) %>%
ggplot(aes(x = quarter, y = income)) +
geom_line() +
labs(title="original_income")
plot4 <- indice_df %>%
ggplot(aes(x = quarter, y = income)) +
geom_line() +
labs(title="income_indice")
plot5 <- data_nivel %>%
dplyr::filter((quarter >= as.Date("2000-01-01"))) %>%
ggplot(aes(x = quarter, y = production)) +
geom_line() +
labs(title="original_production")
plot6 <- indice_df %>%
ggplot(aes(x = quarter, y = production)) +
geom_line() +
labs(title="production_indice")
plot7 <- data_nivel %>%
dplyr::filter((quarter >= as.Date("2000-01-01"))) %>%
ggplot(aes(x = quarter, y = savings)) +
geom_line() +
labs(title="original_savings")
plot8 <- indice_df %>%
ggplot(aes(x = quarter, y = savings)) +
geom_line() +
labs(title="savings_indice")
plot9 <- data_nivel %>%
dplyr::filter((quarter >= as.Date("2000-01-01"))) %>%
ggplot(aes(x = quarter, y = unemployment)) +
geom_line() +
labs(title="original_unemployment")
plot10 <- indice_df %>%
ggplot(aes(x = quarter, y = unemployment)) +
geom_line() +
labs(title="unemployment_indice")
Plotando
# Usando a função multiplot() apresentada na aula
multiplot(plot1,plot2)

multiplot(plot3,plot4)

multiplot(plot5,plot6)

multiplot(plot7,plot8)

multiplot(plot9,plot10)

(B) Correlação da taxa de variação, sem índice mas filtrando o primeiro trimestre do ano 2000
correl2 <- cor(data_nivel %>%
filter((quarter >= as.Date("2000-01-01"))) %>%
select(-"quarter")) %>% round(2)
plot2 <- corrplot::corrplot(correl2,
type = "upper",
tl.col = "black",
)

Conseguimos ver nesses gráficos de correlação a diferença entre usar índice ou apenas a taxa de variação para fazer a correlação. Usando um índice, você está normalizando os dados, fazendo com que a leitura da relação da informação fique padronizada. Sendo assim, os dois resultados são diferentes, pois estão em escalas difetentes.
(C) Plot de dispersão em linhas
new_data_nivel <- data_nivel %>%
pivot_longer(-quarter) %>%
select(date = quarter, name, value)
# Plotando gráfico da base de taxa de variação
p <- new_data_nivel %>%
#filter( name %in% c("pmc", "pim_nivel")) %>%
ggplot( aes(x = date, y = round(value,3), color = name)) +
geom_line() +
theme_bw()
ggplotly(p)
# Plotando gráfico da base com o índice
new_indice_df <- indice_df %>%
pivot_longer(-quarter) %>%
select(date = quarter, name, value)
p <- new_indice_df %>%
#filter( name %in% c("pmc", "pim_nivel")) %>%
ggplot( aes(x = date, y = round(value,3), color = name)) +
geom_line() +
theme_bw()
ggplotly(p)
(D) É possível verificar que com os dados normalizados, o resultado final faz mais sentido. E é possível ver as relações entre as variáveis no gráfico de linhas (ao longo do tempo), pois é possível além de confirmar a correlação entre eles, mas saber o momento em que alguma mudança ocorreu. Ex: No gráfico com a base de indice, conforme a taxa de desemprego caia a taxa de crescimento da produção aumentava; O consumo e a renda se acompanham, conforme a renda aumenta o consumo também aumenta.
(E) É possível visualizar alguns movimentos atípicos em alguns momentos da base de dados. A linha de “poupança”, não acompanha um padrão, sendo difícil fazer uma relação direta com outras variáveis.
Séries de tempo, ciclo, sazonalidade e tendência (“retail.xlsx”)
# lendo a base de dados, selecioando um range para a base, excluido o cabeçalho do arquivo, limpando os nomes das colunas e modificando a coluna de "series_id" para "as_date()".
data <- read_excel("retail.xlsx", range = "A2:GH383") %>%
janitor::clean_names() %>%
dplyr::rename(date = colnames(.)[1]) %>%
mutate(date = as_date(date))
# É necessário não selecionar o cabeçalho do arquivo, pois quando se pega o cabeçalho os dados ficam bugados
Plotando a série temporal em ggseasonplot()
plot_sazonal <- df_ts %>%
forecast::ggseasonplot() +
labs(title = "Gráfico Sazonal")
plot_sazonal

Plotando a série temporal em ggmonthplot()
plot_month <- df_ts %>%
forecast::ggmonthplot() +
labs(title = "As linhas azuis representam a média das observações em cada estação.")
plot_month

Plotando a série temporal em geom_line()
plot_line <- df_ts %>%
ggplot(aes(x = data$date, y = ., color = .)) +
geom_line() +
theme_bw()+
labs(x = "Date",
title = "Evolução a.a.")
plot_line

A série possui grande sazonalidade , poucos ciclos e tendencia de crescimento linear
Dataset Spotify
# Fazendo a leitura do dataframe e salvando em um .rds
# spotify_songs <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-01-21/spotify_songs.csv')
#saveRDS(spotify_songs, "df_spotify")
df_song <- readRDS("df_spotify")
# Filtrando base de dados por data, artista, nome da musica, popularidade da musica e genero musical
df_spotfy <- df_song %>%
select(track_album_release_date,track_artist, track_name, track_popularity, playlist_genre) %>%
as_tibble()
# Verificando quantos tipos de gêneros musicais existem na lista e seperando alguns dfs para plotagem
numero_generos <- df_spotfy %>% pull(playlist_genre) %>% unique()
numero_generos
[1] "pop" "rap" "rock" "latin" "r&b" "edm"
# Rap
df_rap <- df_spotfy %>%
filter(playlist_genre == "rap") %>%
mutate(ano = year(as_date(track_album_release_date))) %>%
group_by(ano) %>%
summarise(media = mean(track_popularity))
# Pop
df_pop <- df_spotfy %>%
filter(playlist_genre == "pop") %>%
mutate(ano = year(as_date(track_album_release_date))) %>%
group_by(ano) %>%
summarise(media = mean(track_popularity))
# Rock
df_rock <- df_spotfy %>%
filter(playlist_genre == "rock") %>%
mutate(ano = year(as_date(track_album_release_date))) %>%
group_by(ano) %>%
summarise(media = mean(track_popularity))
# Latin
df_latin <- df_spotfy %>%
filter(playlist_genre == "latin") %>%
mutate(ano = year(as_date(track_album_release_date))) %>%
group_by(ano) %>%
summarise(media = mean(track_popularity))
# R&B
df_r_b <- df_spotfy %>%
filter(playlist_genre == "r&b") %>%
mutate(ano = year(as_date(track_album_release_date))) %>%
group_by(ano) %>%
summarise(media = mean(track_popularity))
# EDM
df_edm <- df_spotfy %>%
filter(playlist_genre == "edm") %>%
mutate(ano = year(as_date(track_album_release_date))) %>%
group_by(ano) %>%
summarise(media = mean(track_popularity))
# Gráfico comparativo da evolução dos generos musicais ao longo dos anos
p <- plot_ly(df_rap, x = ~ano, y = ~media, type = 'scatter', mode = "lines+marker", name = "RAP") %>%
add_trace(data = df_pop, x = ~ano, y = ~round(media,2), name = "POP") %>%
add_trace(data = df_rock, x = ~ano, y = ~round(media,2), name = "ROCK") %>%
add_trace(data = df_latin, x = ~ano, y = ~round(media,2), name = "LATIN") %>%
add_trace(data = df_r_b, x = ~ano, y = ~round(media,2), name = "R&B") %>%
add_trace(data = df_edm, x = ~ano, y = ~round(media,2), name = "EDM") %>%
layout(title = "Evolução dos gostos musicais ao longo dos anos",
xaxis = list(title ="Ano"),
yaxis = list(title ="Média de popularidade a.a.")
)
p
# df_spotfy %>%
# ggplot( aes(x = track_album_release_date, y = track_popularity, color = track_artist)) +
# geom_line()
É possível acompanhar o crescimento dos gêneros musicais através dos anos, e verificar qual se destacou mais em derterminada época.
Video Games Dataset
# Lendo e salvando base de dados de videogames
# video_games <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-07-30/video_games.csv")
#
# saveRDS(video_games, "videogames")]
df_video_game <- readRDS("videogames")
# Analisando a marca VALVE
df_valve <- df_video_game %>%
filter(developer == "Valve")
# Trocando NA para 0
df_valve$price[is.na(df_valve$price)] <- 0
df_game_plot <- df_valve %>% ggplot(aes(x = game, y = price, color = owners))+
geom_point()+
ggtitle("Relação do preço do jogo por quantidade de compras - Valve") +
theme_bw()
ggplotly(df_game_plot)
df_ubsoft <- df_video_game %>%
filter(developer == "Ubisoft Montreal")
# Trocando NA para 0
df_ubsoft$price[is.na(df_ubsoft$price)] <- 0
df2_game_plot <- df_ubsoft %>% ggplot(aes(x = game, y = price, color = owners))+
geom_point()+
ggtitle("Relação do preço do jogo por quantidade de compras - Ubsoft") +
theme_bw()
ggplotly(df2_game_plot)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKYXV0aG9yOiAiUGVkcm8gSGVucmlxdWUgTW9yZWlyYSBQZXJlaXJhIgpvdXRwdXQ6CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCiMjIERvY3VtZW50byBkZSBhbsOhbGlzZSBleHBsb3JhdG9yaWEgZGUgZGFkb3MgZW0gUgoKYGBge3J9CiMgTG9hZCBkZSB2YXJpw6F2ZWlzIGUgZGUgYmlibGlvdGVjYXMKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoem9vKQpsaWJyYXJ5KHRzYm94KQpsaWJyYXJ5KGZvcmVjYXN0KQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeSh4dHMpICMgbGliIHBhcmEgdGltZSBzZXJpZXMKbGlicmFyeShzcG90aWZ5cikKbGlicmFyeShybWFya2Rvd24pCmxpYnJhcnkocHVycnIpCnNvdXJjZSgibXVsdGlwbG90LlIiLCBsb2NhbCA9IFRSVUUpCmBgYAoKIyMjIChBKSBDcmlhw6fDo28gZG8gaW5kaWNlIGRlIHZhcmlhw6fDo28KCmBgYHtyfQppbmRpY2VfdmFyIDwtIGZ1bmN0aW9uKHgpIHsKICBpbmRpY2UgPC0geAogIGluZGljZVsxXSA8LSAxMDAKICBmb3IoaSBpbiAyOmxlbmd0aCh4KSkgewogICAgaW5kaWNlW2ldIDwtICgxICsgeFtpXS8xMDApICogaW5kaWNlW2ktMV0KICB9CiAgcmV0dXJuKGluZGljZSkKfQpgYGAKCiMjIyBGaWx0cmFuZG8gcG9yIGFubwoKYGBge3J9CmxvYWQoZmlsZSA9ICJ1c19jaGFuZ2UucmRhIikKCmRhdGFfbml2ZWwgPC0gdXNfY2hhbmdlICU+JSAKICBjbGVhbl9uYW1lcygpCgoKIyBDcmlhbmRvIG8gREYgY29tIG9zIGluZGljZXMgZSBmaWx0cmFuZG8gcGVsbyBhbm8gCmluZGljZV9kZjwtIGRhdGFfbml2ZWwgJT4lIAogIGZpbHRlcihxdWFydGVyID49IGFzLkRhdGUoIjIwMDAtMDEtMDEiKSkgJT4lIAogIHNlbGVjdCgtcXVhcnRlcikgJT4lIAogIG1hcF9kZihmdW5jdGlvbih4KSB4ICU+JSBpbmRpY2VfdmFyKCkpCgojIENyaWFuZG8gREYgY29tIGEgY29sdW5hIGRlIGRhdGEgZGEgYmFzZSBvcmlnaW5hbAoKZGZfZGF0ZSA8LSBkYXRhX25pdmVsICU+JSAKICAgZmlsdGVyKHF1YXJ0ZXIgPj0gYXMuRGF0ZSgiMjAwMC0wMS0wMSIpKSAlPiUgCiAgIHNlbGVjdChxdWFydGVyKQoKIyBDcmlhbmRvIGEgY29sdW5hIHF1YXJ0ZXIgZGUgdm9sdGEgbmEgYmFzZSBkZSBpbmRpY2VzCmluZGljZV9kZiA8LSBpbmRpY2VfZGYgJT4lIAogIG11dGF0ZShxdWFydGVyID0gZGZfZGF0ZSRxdWFydGVyKQoKCgpgYGAKCiMjIyMgTXVsdGlwbG90IGRhdGEKCmBgYHtyfQpwbG90MSA8LSBkYXRhX25pdmVsICU+JSAKICBkcGx5cjo6ZmlsdGVyKChxdWFydGVyID49IGFzLkRhdGUoIjIwMDAtMDEtMDEiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gY29uc3VtcHRpb24pKSArIAogICAgZ2VvbV9saW5lKCkgKwogICAgbGFicyh0aXRsZT0ib3JpZ2luYWxfY29uc3VwdGlvbiIpCnBsb3QyIDwtIGluZGljZV9kZiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGNvbnN1bXB0aW9uKSkgKyAKICAgIGdlb21fbGluZSgpICsKICAgIGxhYnModGl0bGU9ImNvbnN1cHRpb25faW5kaWNlIikKcGxvdDMgPC0gZGF0YV9uaXZlbCAlPiUgCiAgZHBseXI6OmZpbHRlcigocXVhcnRlciA+PSBhcy5EYXRlKCIyMDAwLTAxLTAxIikpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGluY29tZSkpICsgCiAgICBnZW9tX2xpbmUoKSArCiAgICBsYWJzKHRpdGxlPSJvcmlnaW5hbF9pbmNvbWUiKQpwbG90NCA8LSBpbmRpY2VfZGYgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBpbmNvbWUpKSArIAogICAgZ2VvbV9saW5lKCkgKwogICAgbGFicyh0aXRsZT0iaW5jb21lX2luZGljZSIpCnBsb3Q1IDwtIGRhdGFfbml2ZWwgJT4lIAogIGRwbHlyOjpmaWx0ZXIoKHF1YXJ0ZXIgPj0gYXMuRGF0ZSgiMjAwMC0wMS0wMSIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBwcm9kdWN0aW9uKSkgKyAKICAgIGdlb21fbGluZSgpICsKICAgIGxhYnModGl0bGU9Im9yaWdpbmFsX3Byb2R1Y3Rpb24iKQpwbG90NiA8LSBpbmRpY2VfZGYgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBwcm9kdWN0aW9uKSkgKyAKICAgIGdlb21fbGluZSgpICsKICAgIGxhYnModGl0bGU9InByb2R1Y3Rpb25faW5kaWNlIikKcGxvdDcgPC0gZGF0YV9uaXZlbCAlPiUgCiAgZHBseXI6OmZpbHRlcigocXVhcnRlciA+PSBhcy5EYXRlKCIyMDAwLTAxLTAxIikpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHNhdmluZ3MpKSArIAogICAgZ2VvbV9saW5lKCkgKwogICAgbGFicyh0aXRsZT0ib3JpZ2luYWxfc2F2aW5ncyIpCnBsb3Q4IDwtIGluZGljZV9kZiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHNhdmluZ3MpKSArIAogICAgZ2VvbV9saW5lKCkgKwogICAgbGFicyh0aXRsZT0ic2F2aW5nc19pbmRpY2UiKQpwbG90OSA8LSBkYXRhX25pdmVsICU+JSAKICBkcGx5cjo6ZmlsdGVyKChxdWFydGVyID49IGFzLkRhdGUoIjIwMDAtMDEtMDEiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdW5lbXBsb3ltZW50KSkgKyAKICAgIGdlb21fbGluZSgpICsKICAgIGxhYnModGl0bGU9Im9yaWdpbmFsX3VuZW1wbG95bWVudCIpCnBsb3QxMCA8LSBpbmRpY2VfZGYgJT4lIAogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSB1bmVtcGxveW1lbnQpKSArIAogICAgZ2VvbV9saW5lKCkgKwogICAgbGFicyh0aXRsZT0idW5lbXBsb3ltZW50X2luZGljZSIpCmBgYAoKIyMjIyBQbG90YW5kbwoKYGBge3J9CiMgVXNhbmRvIGEgZnVuw6fDo28gbXVsdGlwbG90KCkgYXByZXNlbnRhZGEgbmEgYXVsYQptdWx0aXBsb3QocGxvdDEscGxvdDIpCmBgYAoKYGBge3J9Cm11bHRpcGxvdChwbG90MyxwbG90NCkKYGBgCgpgYGB7cn0KbXVsdGlwbG90KHBsb3Q1LHBsb3Q2KQpgYGAKCmBgYHtyfQptdWx0aXBsb3QocGxvdDcscGxvdDgpCmBgYAoKYGBge3J9Cm11bHRpcGxvdChwbG90OSxwbG90MTApCmBgYAoKCiMjIyMgKEIpIENvcnJlbGHDp8OjbyBjb20gaW5kaWNlIDEwMCBwYXJhIG8gcHJpbWVpcm8gdHJpbWVzdHJlIGRvIGFubyAyMDAwCgoKYGBge3J9CmNvcnJlbCA8LSAgY29yKGluZGljZV9kZiAlPiUgCiAgICAgIHNlbGVjdCgtInF1YXJ0ZXIiKSkgJT4lIHJvdW5kKDIpIAoKcGxvdDEgPC0gY29ycnBsb3Q6OmNvcnJwbG90KGNvcnJlbCwgCiAgICAgICAgICAgICAgICAgICB0eXBlID0gInVwcGVyIiwKICAgICAgICAgICAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgICApCgpgYGAKCiMjIyMgKEIpIENvcnJlbGHDp8OjbyBkYSB0YXhhIGRlIHZhcmlhw6fDo28sIHNlbSDDrW5kaWNlIG1hcyBmaWx0cmFuZG8gbyBwcmltZWlybyB0cmltZXN0cmUgZG8gYW5vIDIwMDAKCmBgYHtyfQpjb3JyZWwyIDwtICBjb3IoZGF0YV9uaXZlbCAlPiUgCiAgICAgICAgICAgICAgICAgIGZpbHRlcigocXVhcnRlciA+PSBhcy5EYXRlKCIyMDAwLTAxLTAxIikpKSAlPiUgCiAgICAgICAgICAgICAgICAgIHNlbGVjdCgtInF1YXJ0ZXIiKSkgJT4lIHJvdW5kKDIpIAoKcGxvdDIgPC0gY29ycnBsb3Q6OmNvcnJwbG90KGNvcnJlbDIsIAogICAgICAgICAgICAgICAgICAgdHlwZSA9ICJ1cHBlciIsCiAgICAgICAgICAgICAgICAgICB0bC5jb2wgPSAiYmxhY2siLAogICAgICAgICAgICAgICAgICAgKQpgYGAKIyMjIyBDb25zZWd1aW1vcyB2ZXIgbmVzc2VzIGdyw6FmaWNvcyBkZSBjb3JyZWxhw6fDo28gYSBkaWZlcmVuw6dhIGVudHJlIHVzYXIgw61uZGljZSBvdSBhcGVuYXMgYSB0YXhhIGRlIHZhcmlhw6fDo28gcGFyYSBmYXplciBhIGNvcnJlbGHDp8Ojby4gVXNhbmRvIHVtIMOtbmRpY2UsIHZvY8OqIGVzdMOhIG5vcm1hbGl6YW5kbyBvcyBkYWRvcywgZmF6ZW5kbyBjb20gcXVlIGEgbGVpdHVyYSBkYSByZWxhw6fDo28gZGEgaW5mb3JtYcOnw6NvIGZpcXVlIHBhZHJvbml6YWRhLiBTZW5kbyBhc3NpbSwgb3MgZG9pcyByZXN1bHRhZG9zIHPDo28gZGlmZXJlbnRlcywgcG9pcyBlc3TDo28gZW0gZXNjYWxhcyBkaWZldGVudGVzLgoKCiMjIyAoQykgUGxvdCBkZSBkaXNwZXJzw6NvIGVtIGxpbmhhcwpgYGB7cn0KCm5ld19kYXRhX25pdmVsIDwtIGRhdGFfbml2ZWwgJT4lIAogIHBpdm90X2xvbmdlcigtcXVhcnRlcikgJT4lIAogIHNlbGVjdChkYXRlID0gcXVhcnRlciwgbmFtZSwgdmFsdWUpCgojIFBsb3RhbmRvIGdyw6FmaWNvIGRhIGJhc2UgZGUgdGF4YSBkZSB2YXJpYcOnw6NvCnAgPC0gbmV3X2RhdGFfbml2ZWwgJT4lIAogICNmaWx0ZXIoIG5hbWUgJWluJSBjKCJwbWMiLCAicGltX25pdmVsIikpICU+JSAKICBnZ3Bsb3QoIGFlcyh4ID0gZGF0ZSwgeSA9IHJvdW5kKHZhbHVlLDMpLCBjb2xvciA9IG5hbWUpKSArCiAgZ2VvbV9saW5lKCkgKwogIHRoZW1lX2J3KCkKZ2dwbG90bHkocCkKYGBgCgpgYGB7cn0KIyBQbG90YW5kbyBncsOhZmljbyBkYSBiYXNlIGNvbSBvIMOtbmRpY2UgCm5ld19pbmRpY2VfZGYgPC0gaW5kaWNlX2RmICU+JSAKICBwaXZvdF9sb25nZXIoLXF1YXJ0ZXIpICU+JSAKICBzZWxlY3QoZGF0ZSA9IHF1YXJ0ZXIsIG5hbWUsIHZhbHVlKQoKcCA8LSBuZXdfaW5kaWNlX2RmICU+JSAKICAjZmlsdGVyKCBuYW1lICVpbiUgYygicG1jIiwgInBpbV9uaXZlbCIpKSAlPiUgCiAgZ2dwbG90KCBhZXMoeCA9IGRhdGUsIHkgPSByb3VuZCh2YWx1ZSwzKSwgY29sb3IgPSBuYW1lKSkgKwogIGdlb21fbGluZSgpICsKICB0aGVtZV9idygpCmdncGxvdGx5KHApCmBgYAoKCgojIyMjIChEKSDDiSBwb3Nzw612ZWwgdmVyaWZpY2FyIHF1ZSBjb20gb3MgZGFkb3Mgbm9ybWFsaXphZG9zLCBvIHJlc3VsdGFkbyBmaW5hbCBmYXogbWFpcyBzZW50aWRvLiBFIMOpIHBvc3PDrXZlbCB2ZXIgYXMgcmVsYcOnw7VlcyBlbnRyZSBhcyB2YXJpw6F2ZWlzIG5vIGdyw6FmaWNvIGRlIGxpbmhhcyAoYW8gbG9uZ28gZG8gdGVtcG8pLCBwb2lzIMOpIHBvc3PDrXZlbCBhbMOpbSBkZSBjb25maXJtYXIgYSBjb3JyZWxhw6fDo28gZW50cmUgZWxlcywgbWFzIHNhYmVyIG8gbW9tZW50byBlbSBxdWUgYWxndW1hIG11ZGFuw6dhIG9jb3JyZXUuIEV4OiBObyBncsOhZmljbyBjb20gYSBiYXNlIGRlIGluZGljZSwgY29uZm9ybWUgYSB0YXhhIGRlIGRlc2VtcHJlZ28gY2FpYSBhIHRheGEgZGUgY3Jlc2NpbWVudG8gZGEgcHJvZHXDp8OjbyBhdW1lbnRhdmE7IE8gY29uc3VtbyBlIGEgcmVuZGEgc2UgYWNvbXBhbmhhbSwgY29uZm9ybWUgYSByZW5kYSBhdW1lbnRhIG8gY29uc3VtbyB0YW1iw6ltIGF1bWVudGEuCgojIyMjIChFKSDDiSBwb3Nzw612ZWwgdmlzdWFsaXphciBhbGd1bnMgbW92aW1lbnRvcyBhdMOtcGljb3MgZW0gYWxndW5zIG1vbWVudG9zIGRhIGJhc2UgZGUgZGFkb3MuIEEgbGluaGEgZGUgInBvdXBhbsOnYSIsIG7Do28gYWNvbXBhbmhhIHVtIHBhZHLDo28sIHNlbmRvIGRpZsOtY2lsIGZhemVyIHVtYSByZWxhw6fDo28gZGlyZXRhIGNvbSBvdXRyYXMgdmFyacOhdmVpcy4KCgojIyBTw6lyaWVzIGRlIHRlbXBvLCBjaWNsbywgc2F6b25hbGlkYWRlIGUgdGVuZMOqbmNpYSAoInJldGFpbC54bHN4IikKCmBgYHtyfQojIGxlbmRvIGEgYmFzZSBkZSBkYWRvcywgc2VsZWNpb2FuZG8gdW0gcmFuZ2UgcGFyYSBhIGJhc2UsIGV4Y2x1aWRvIG8gY2FiZcOnYWxobyBkbyBhcnF1aXZvLCBsaW1wYW5kbyBvcyBub21lcyBkYXMgY29sdW5hcyBlIG1vZGlmaWNhbmRvIGEgY29sdW5hIGRlICAic2VyaWVzX2lkIiBwYXJhICJhc19kYXRlKCkiLgpkYXRhIDwtIHJlYWRfZXhjZWwoInJldGFpbC54bHN4IiwgcmFuZ2UgPSAiQTI6R0gzODMiKSAlPiUgCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgCiAgZHBseXI6OnJlbmFtZShkYXRlID0gY29sbmFtZXMoLilbMV0pICU+JSAKICBtdXRhdGUoZGF0ZSA9IGFzX2RhdGUoZGF0ZSkpCgojIMOJIG5lY2Vzc8OhcmlvIG7Do28gc2VsZWNpb25hciBvIGNhYmXDp2FsaG8gZG8gYXJxdWl2bywgcG9pcyBxdWFuZG8gc2UgcGVnYSBvIGNhYmXDp2FsaG8gb3MgZGFkb3MgZmljYW0gYnVnYWRvcwoKYGBgCgojIyMjIENyaWFuZG8gdW0gbm92byBkYXRhZnJhbWUgZSBvIHRyYW5zZm9ybWFuZG8gZW0gdGltZSBzZXJpZXMKYGBge3J9CmRmX3RzIDwtIGRhdGEkYTMzNDkzMzV0JT4lIAogIHN0YXRzOjp0cygKICAgIHN0YXJ0ID0gYygKICAgICAgbHVicmlkYXRlOjp5ZWFyKGRwbHlyOjpmaXJzdChkYXRhJGRhdGUpKSwKICAgICAgbHVicmlkYXRlOjptb250aChkcGx5cjo6Zmlyc3QoZGF0YSRkYXRlKSkKICAgICksCiAgICBlbmQgPSBjKAogICAgICBsdWJyaWRhdGU6OnllYXIoZHBseXI6Omxhc3QoZGF0YSRkYXRlKSksCiAgICAgIGx1YnJpZGF0ZTo6bW9udGgoZHBseXI6Omxhc3QoZGF0YSRkYXRlKSkKICAgICksCiAgICBmcmVxdWVuY3kgPSAxMgogICkKYGBgCgojIyMjIFBsb3RhbmRvIGEgc8OpcmllIHRlbXBvcmFsIGVtIGdnc2Vhc29ucGxvdCgpCmBgYHtyfQpwbG90X3Nhem9uYWwgPC0gZGZfdHMgJT4lIAogIGZvcmVjYXN0OjpnZ3NlYXNvbnBsb3QoKSArIAogIGxhYnModGl0bGUgPSAiR3LDoWZpY28gU2F6b25hbCIpCnBsb3Rfc2F6b25hbAoKYGBgCgojIyMjIFBsb3RhbmRvIGEgc8OpcmllIHRlbXBvcmFsIGVtIGdnbW9udGhwbG90KCkKYGBge3J9CnBsb3RfbW9udGggPC0gZGZfdHMgJT4lIAogIGZvcmVjYXN0OjpnZ21vbnRocGxvdCgpICsgCiAgbGFicyh0aXRsZSA9ICJBcyBsaW5oYXMgYXp1aXMgcmVwcmVzZW50YW0gYSBtw6lkaWEgZGFzIG9ic2VydmHDp8O1ZXMgZW0gY2FkYSBlc3Rhw6fDo28uIikKcGxvdF9tb250aAoKYGBgCgojIyMjIFBsb3RhbmRvIGEgc8OpcmllIHRlbXBvcmFsIGVtIGdlb21fbGluZSgpCmBgYHtyfQpwbG90X2xpbmUgPC0gZGZfdHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGEkZGF0ZSwgeSA9IC4sIGNvbG9yID0gLikpICsgCiAgZ2VvbV9saW5lKCkgKwogIHRoZW1lX2J3KCkrCiAgbGFicyh4ID0gIkRhdGUiLAogICAgICAgdGl0bGUgPSAiRXZvbHXDp8OjbyBhLmEuIikKcGxvdF9saW5lCgpgYGAKCiMjIyMgQSBzw6lyaWUgcG9zc3VpIGdyYW5kZSBzYXpvbmFsaWRhZGUgLCBwb3Vjb3MgY2ljbG9zIGUgdGVuZGVuY2lhIGRlIGNyZXNjaW1lbnRvIGxpbmVhcgoKIyMjIERhdGFzZXQgU3BvdGlmeSAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgRmF6ZW5kbyBhIGxlaXR1cmEgZG8gZGF0YWZyYW1lIGUgc2FsdmFuZG8gZW0gdW0gLnJkcwojIHNwb3RpZnlfc29uZ3MgPC0gcmVhZHI6OnJlYWRfY3N2KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMjAvMjAyMC0wMS0yMS9zcG90aWZ5X3NvbmdzLmNzdicpCiNzYXZlUkRTKHNwb3RpZnlfc29uZ3MsICJkZl9zcG90aWZ5IikKCgpkZl9zb25nIDwtIHJlYWRSRFMoImRmX3Nwb3RpZnkiKQoKIyBGaWx0cmFuZG8gYmFzZSBkZSBkYWRvcyBwb3IgZGF0YSwgYXJ0aXN0YSwgbm9tZSBkYSBtdXNpY2EsIHBvcHVsYXJpZGFkZSBkYSBtdXNpY2EgZSBnZW5lcm8gbXVzaWNhbApkZl9zcG90ZnkgPC0gZGZfc29uZyAlPiUgCiAgc2VsZWN0KHRyYWNrX2FsYnVtX3JlbGVhc2VfZGF0ZSx0cmFja19hcnRpc3QsIHRyYWNrX25hbWUsIHRyYWNrX3BvcHVsYXJpdHksIHBsYXlsaXN0X2dlbnJlKSAlPiUgCiAgYXNfdGliYmxlKCkKCiMgVmVyaWZpY2FuZG8gcXVhbnRvcyB0aXBvcyBkZSBnw6puZXJvcyBtdXNpY2FpcyBleGlzdGVtIG5hIGxpc3RhIGUgc2VwZXJhbmRvIGFsZ3VucyBkZnMgcGFyYSBwbG90YWdlbQpudW1lcm9fZ2VuZXJvcyA8LSBkZl9zcG90ZnkgJT4lIHB1bGwocGxheWxpc3RfZ2VucmUpICU+JSB1bmlxdWUoKQpudW1lcm9fZ2VuZXJvcwoKIyBSYXAgCmRmX3JhcCA8LSBkZl9zcG90ZnkgJT4lIAogIGZpbHRlcihwbGF5bGlzdF9nZW5yZSA9PSAicmFwIikgJT4lIAogIG11dGF0ZShhbm8gPSB5ZWFyKGFzX2RhdGUodHJhY2tfYWxidW1fcmVsZWFzZV9kYXRlKSkpICU+JSAKICBncm91cF9ieShhbm8pICU+JSAKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKHRyYWNrX3BvcHVsYXJpdHkpKQoKIyBQb3AgCmRmX3BvcCA8LSBkZl9zcG90ZnkgJT4lIAogIGZpbHRlcihwbGF5bGlzdF9nZW5yZSA9PSAicG9wIikgJT4lIAogIG11dGF0ZShhbm8gPSB5ZWFyKGFzX2RhdGUodHJhY2tfYWxidW1fcmVsZWFzZV9kYXRlKSkpICU+JSAKICBncm91cF9ieShhbm8pICU+JSAKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKHRyYWNrX3BvcHVsYXJpdHkpKQoKIyBSb2NrIApkZl9yb2NrIDwtIGRmX3Nwb3RmeSAlPiUgCiAgZmlsdGVyKHBsYXlsaXN0X2dlbnJlID09ICJyb2NrIikgJT4lIAogIG11dGF0ZShhbm8gPSB5ZWFyKGFzX2RhdGUodHJhY2tfYWxidW1fcmVsZWFzZV9kYXRlKSkpICU+JSAKICBncm91cF9ieShhbm8pICU+JSAKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKHRyYWNrX3BvcHVsYXJpdHkpKQoKIyBMYXRpbiAKZGZfbGF0aW4gPC0gZGZfc3BvdGZ5ICU+JSAKICBmaWx0ZXIocGxheWxpc3RfZ2VucmUgPT0gImxhdGluIikgJT4lIAogIG11dGF0ZShhbm8gPSB5ZWFyKGFzX2RhdGUodHJhY2tfYWxidW1fcmVsZWFzZV9kYXRlKSkpICU+JSAKICBncm91cF9ieShhbm8pICU+JSAKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKHRyYWNrX3BvcHVsYXJpdHkpKQoKIyBSJkIgCmRmX3JfYiA8LSBkZl9zcG90ZnkgJT4lIAogIGZpbHRlcihwbGF5bGlzdF9nZW5yZSA9PSAiciZiIikgJT4lIAogIG11dGF0ZShhbm8gPSB5ZWFyKGFzX2RhdGUodHJhY2tfYWxidW1fcmVsZWFzZV9kYXRlKSkpICU+JSAKICBncm91cF9ieShhbm8pICU+JSAKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKHRyYWNrX3BvcHVsYXJpdHkpKQoKIyBFRE0gCmRmX2VkbSA8LSBkZl9zcG90ZnkgJT4lIAogIGZpbHRlcihwbGF5bGlzdF9nZW5yZSA9PSAiZWRtIikgJT4lIAogIG11dGF0ZShhbm8gPSB5ZWFyKGFzX2RhdGUodHJhY2tfYWxidW1fcmVsZWFzZV9kYXRlKSkpICU+JSAKICBncm91cF9ieShhbm8pICU+JSAKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKHRyYWNrX3BvcHVsYXJpdHkpKQoKIyBHcsOhZmljbyBjb21wYXJhdGl2byBkYSBldm9sdcOnw6NvIGRvcyBnZW5lcm9zIG11c2ljYWlzIGFvIGxvbmdvIGRvcyBhbm9zCnAgPC0gcGxvdF9seShkZl9yYXAsIHggPSB+YW5vLCB5ID0gfm1lZGlhLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gImxpbmVzK21hcmtlciIsIG5hbWUgPSAiUkFQIikgJT4lIAogICAgYWRkX3RyYWNlKGRhdGEgPSBkZl9wb3AsIHggPSB+YW5vLCB5ID0gfnJvdW5kKG1lZGlhLDIpLCBuYW1lID0gIlBPUCIpICU+JSAKICAgIGFkZF90cmFjZShkYXRhID0gZGZfcm9jaywgeCA9IH5hbm8sIHkgPSB+cm91bmQobWVkaWEsMiksIG5hbWUgPSAiUk9DSyIpICU+JSAKICAgIGFkZF90cmFjZShkYXRhID0gZGZfbGF0aW4sIHggPSB+YW5vLCB5ID0gfnJvdW5kKG1lZGlhLDIpLCBuYW1lID0gIkxBVElOIikgJT4lIAogICAgYWRkX3RyYWNlKGRhdGEgPSBkZl9yX2IsIHggPSB+YW5vLCB5ID0gfnJvdW5kKG1lZGlhLDIpLCBuYW1lID0gIlImQiIpICU+JSAKICAgIGFkZF90cmFjZShkYXRhID0gZGZfZWRtLCB4ID0gfmFubywgeSA9IH5yb3VuZChtZWRpYSwyKSwgbmFtZSA9ICJFRE0iKSAlPiUgCiAgICAgIGxheW91dCh0aXRsZSA9ICJFdm9sdcOnw6NvIGRvcyBnb3N0b3MgbXVzaWNhaXMgYW8gbG9uZ28gZG9zIGFub3MiLAogICAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0iQW5vIiksCiAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSJNw6lkaWEgZGUgcG9wdWxhcmlkYWRlIGEuYS4iKQogICAgICAgICAgICAgKQpwCgojIGRmX3Nwb3RmeSAlPiUKIyAgICAgZ2dwbG90KCBhZXMoeCA9IHRyYWNrX2FsYnVtX3JlbGVhc2VfZGF0ZSwgeSA9IHRyYWNrX3BvcHVsYXJpdHksIGNvbG9yID0gdHJhY2tfYXJ0aXN0KSkgKwojICAgICBnZW9tX2xpbmUoKQoKYGBgCgojIyMjIMOJIHBvc3PDrXZlbCBhY29tcGFuaGFyIG8gY3Jlc2NpbWVudG8gZG9zIGfDqm5lcm9zIG11c2ljYWlzIGF0cmF2w6lzIGRvcyBhbm9zLCBlIHZlcmlmaWNhciBxdWFsIHNlIGRlc3RhY291IG1haXMgZW0gZGVydGVybWluYWRhIMOpcG9jYS4KCiMjIyBWaWRlbyBHYW1lcyBEYXRhc2V0CgpgYGB7cn0KIyBMZW5kbyBlIHNhbHZhbmRvIGJhc2UgZGUgZGFkb3MgZGUgdmlkZW9nYW1lcwojIHZpZGVvX2dhbWVzIDwtIHJlYWRyOjpyZWFkX2NzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9tYXN0ZXIvZGF0YS8yMDE5LzIwMTktMDctMzAvdmlkZW9fZ2FtZXMuY3N2IikKIyAKIyBzYXZlUkRTKHZpZGVvX2dhbWVzLCAidmlkZW9nYW1lcyIpXQoKZGZfdmlkZW9fZ2FtZSA8LSByZWFkUkRTKCJ2aWRlb2dhbWVzIikKCiMgQW5hbGlzYW5kbyBhIG1hcmNhIFZBTFZFCgpkZl92YWx2ZSA8LSBkZl92aWRlb19nYW1lICU+JSAKICBmaWx0ZXIoZGV2ZWxvcGVyID09ICJWYWx2ZSIpIAoKIyBUcm9jYW5kbyBOQSBwYXJhIDAKZGZfdmFsdmUkcHJpY2VbaXMubmEoZGZfdmFsdmUkcHJpY2UpXSA8LSAwCgpkZl9nYW1lX3Bsb3QgPC0gZGZfdmFsdmUgJT4lIGdncGxvdChhZXMoeCA9IGdhbWUsIHkgPSBwcmljZSwgY29sb3IgPSBvd25lcnMpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2d0aXRsZSgiUmVsYcOnw6NvIGRvIHByZcOnbyBkbyBqb2dvIHBvciBxdWFudGlkYWRlIGRlIGNvbXByYXMgLSBWYWx2ZSIpICsgCiAgdGhlbWVfYncoKQoKZ2dwbG90bHkoZGZfZ2FtZV9wbG90KQpgYGAKCmBgYHtyfQpkZl91YnNvZnQgPC0gZGZfdmlkZW9fZ2FtZSAlPiUgCiAgZmlsdGVyKGRldmVsb3BlciA9PSAiVWJpc29mdCBNb250cmVhbCIpIAoKIyBUcm9jYW5kbyBOQSBwYXJhIDAKZGZfdWJzb2Z0JHByaWNlW2lzLm5hKGRmX3Vic29mdCRwcmljZSldIDwtIDAKCmRmMl9nYW1lX3Bsb3QgPC0gZGZfdWJzb2Z0ICU+JSBnZ3Bsb3QoYWVzKHggPSBnYW1lLCB5ID0gcHJpY2UsIGNvbG9yID0gb3duZXJzKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdndGl0bGUoIlJlbGHDp8OjbyBkbyBwcmXDp28gZG8gam9nbyBwb3IgcXVhbnRpZGFkZSBkZSBjb21wcmFzIC0gVWJzb2Z0IikgKyAKICB0aGVtZV9idygpCgpnZ3Bsb3RseShkZjJfZ2FtZV9wbG90KQpgYGAKCg==